﻿using System.Linq;
using EzDesk.DesktopClient.Command;
using EzDesk.DesktopClient.Model;
using EzDesk.DesktopClient.UtilityView.ViewModel;
using EzDesk.EventAggregation;
using EzDesk.DesktopClient.Event;
using EzDesk.Generic;
using EzDesk.Generic.Collections;
using System;
using EzDesk.DesktopClient.MVVMEnhance;
using Microsoft.Practices.Unity;

namespace EzDesk.DesktopClient.PopupModule.ViewModel
{
    public class PopupViewModel : ViewModelWithSingleContainer<IPopupView>
    {

        #region Fields
        private int _selectedIndex = 0;
        private const int PreloadCount = 10;
        public DelegateCommand NextFeedCommand { get; set; }
        public DelegateCommand PrevFeedCommand { get; set; }
        public DelegateCommand CloseAllFeedsCommand { get; set; }
        private RangeCollection<UpdateItemViewModel> _tipPopFeeds;
        private EventSubscriptor<FeedPushArgs> _feedPushToken;
        private IDataManagement _dataManagement;
        

        //Should read from config
        private static bool AutoShow
        {
            get
            {
                return true;
            }
        }

        #endregion Fields

        #region Constructor
        public PopupViewModel()
            : base()
        {
            Init();
        }

        public PopupViewModel(IUnityContainer unityContainer,IDataManagement dataManagement)
        {
            this.Container = unityContainer;
            _dataManagement = dataManagement;
            Init();
        }

        private void Init()
        {
            InitField();
            InitEvent();
        }


        #region Init
        private void InitField()
        {
            _tipPopFeeds = new RangeCollection<UpdateItemViewModel>(PreloadCount);

            this.NextFeedCommand = new DelegateCommand(this.GoNextFeed);
            this.PrevFeedCommand = new DelegateCommand(this.OnPrevFeed);
            this.CloseAllFeedsCommand = new DelegateCommand(this.OnCloseAllFeeds);
        }

        private void InitEvent()
        {
            InitGlobalEvent();
            InitViewEvent();
        }

        private void InitViewEvent()
        {
            this.View.OnWindowMinimize += (o,e)=>this._tipPopFeeds.Clear();
            this.View.OnNavigate += OnNavigate;


        }

        private void InitGlobalEvent()
        {
            _feedPushToken =  FeedPushEvent.Instance.Subscribe(OnFeedUpdate, ThreadOption.UIThread);
        }
        #endregion Init

        #endregion Constructor

        private void GoNextFeed()
        {
            if (_selectedIndex < _tipPopFeeds.Count - 1)
            {
                _selectedIndex += 1;
                ChangeCurrentFeed();
            }
        }

        private void OnPrevFeed()
        {
            if (_selectedIndex > 0)
            {
                _selectedIndex -= 1;
                ChangeCurrentFeed();
            }
        }

        private void OnCloseAllFeeds()
        {
            foreach (var itemViewModel in _tipPopFeeds)
            {
                itemViewModel.IsRead = true;
                UpdateDataManagement.Instance.UpdateFeedStatusInCache(itemViewModel.FeedModel);
                itemViewModel.Dispose();
            }
            _tipPopFeeds.Clear();
        }

        #region Properties

        public bool HasData
        {
            get
            {
                return _tipPopFeeds.Count > _selectedIndex + 1;
            }
        }

        public int SelectedIndex
        {
            get
            {
                return _selectedIndex + 1;
            }
        }
        public int LeftCount
        {
            get
            { return _tipPopFeeds.Count - _selectedIndex - 1; }
        }

        public int Count
        {
            get { return _tipPopFeeds.Count; }
        }

        public UpdateItemViewModel CurrentFeedViewModel
        {
            get
            {
                if (_tipPopFeeds.Count == 0) return null;
                return _tipPopFeeds[_selectedIndex];
            }
        }
        #endregion Properties

        #region EventMethod
        public void OnFeedUpdate(FeedPushArgs args)
        {
            ProcessData(args);
            ProcessView();
        }
        private void ProcessData(FeedPushArgs args)
        {

            //这里采用比较UpdateOn和LastChangeOn的时间，来判断Feed到底是被UpdateOn还是LastChangeOn
            //UpdateOn对应了数据变更
            //LastChangeOn对应了状态变更


            args.UpdateCollection
                .Where(feed=>feed.UpdateOn >= feed.LastChangeOn)
                .Foreach(ProcessPushUpdate);

            ChangeCurrentFeed();
        }

        private void OnNavigate(object sender, GenericEventArg<string> e)
        {
            CurrentFeedViewModel.IsRead = true;
            FeedStatusChangeEvent.Instance.Publish(CurrentFeedViewModel.FeedModel);
            FunctionNavigateEvent.Instance.Publish(new FunctionNavigateArgs { Url = e.Value });
            if (_selectedIndex == _tipPopFeeds.Count - 1)
                _selectedIndex -= 1;
            _tipPopFeeds.Remove(CurrentFeedViewModel);
            RaiseChanges();

        }

        private void ChangeCurrentFeed()
        {
            RaiseChanges();
            View.ResizeWindow();
        }

        private void RaiseChanges()
        {
            RaisePropertyChanged("SelectedIndex");
            RaisePropertyChanged("Count");
            RaisePropertyChanged("CurrentFeedViewModel");
            RaisePropertyChanged("LeftCount");
            RaisePropertyChanged("HasData");
        }

        private void ProcessView()
        {
            if (HasData)
            {
                AutoShow.TrueDo(View.PopupShow);
            }
        }



        #endregion EventMethod

        #region Remove dup feed on UI
        private void ProcessPushUpdate(Feed feed)
        {
            var updateItemViewModel = _tipPopFeeds.FirstOrDefault(uvm => uvm.FeedModel.FeedID == feed.FeedID);
            if (updateItemViewModel != null)
            {
                if (updateItemViewModel.FeedModel.UpdateOn != feed.UpdateOn)
                {
                    _tipPopFeeds.Remove(updateItemViewModel);
                    _tipPopFeeds.InsertItemAtFirst(Container.Resolve<UpdateItemViewModel>().SetModel(feed));
                }
                if (updateItemViewModel.FeedModel.LastChangeOn != feed.LastChangeOn)
                {
                    if (!feed.IsAvailable.Value && feed.IsRead.Value)
                    {
                        _tipPopFeeds.Remove(updateItemViewModel);
                    }
                }
            }
            else
            {
                if (feed.IsAvailable.Value)
                    _tipPopFeeds.InsertItemAtFirst(Container.Resolve<UpdateItemViewModel>().SetModel(feed));
            }
        }
        #endregion 

        protected override void OnDispose()
        {
            this.View.CloseWindowView();

            _tipPopFeeds.Foreach(f => f.Dispose());
            _tipPopFeeds.Clear();

            _feedPushToken.Dispose();
            base.OnDispose();
        }
    }
}